/**
 * 模态弹窗组件
 * */
;!function(window,undefined){
    "use strict";

    var isLucky = window.lucky && lucky.define, $, ready = {
        getPath: function(){
            var jsPath = document.currentScript ? document.currentScript.src : function(){
                var js = document.scripts
                    ,last = js.length - 1
                    ,src;
                for(var i = last; i > 0; i--){
                    if(js[i].readyState === 'interactive'){
                        src = js[i].src;
                        break;
                    }
                }
                return src || js[last].src;
            }();
            return jsPath.substring(0, jsPath.lastIndexOf('/') + 1);
        }(),
        config: {},
        end: {},
        minIndex: 0,
        minLeft: [],
        type: ['dialog', 'page', 'iframe', 'loading'],
        getStyle: function(node, name){
            var style = node.currentStyle ? node.currentStyle : window.getComputedStyle(node, null);
            return style[style.getPropertyValue ? 'getPropertyValue' : 'getAttribute'](name);
        },
        //载入CSS
        link: function (href, fn, cssname) {

            if(!modal.path) return;

            var head = document.getElementsByTagName("head")[0],
                link = document.createElement('link');
            if(typeof fn === 'string'){
                cssname = fn;
            }
            var app = (cssname || href).replace(/\.|\//g, '');
            var id = 'luckycss-' + app, timeout = 0;

            link.rel = 'stylesheet';
            link.href = modal.path + href;
            link.id = id;

            if(!document.getElementById(id)){
                head.appendChild(link);
            }

            if(!document.getElementById(id)){
                head.appendChild(link);
            }

            if(typeof fn !== 'function'){
                return;
            }
            //轮询css是否加载完毕
            (function poll() {
                if(++timeout > 8 * 1000 / 100){
                    return window.console && console.error('modal.css: Invalid');
                };
                parseInt(ready.getStyle(document.getElementById(id), 'width')) === 1989 ? fn() : setTimeout(poll, 100);
            }());
        }
    };

    //内置方法
    var modal = {
        v: '0.0.1',
        index:(window.modal && window.modal.v) ? 100000:0,
        path: ready.getPath,
        //窗口大小
        sizeEnums: ['','xl','lg','sm','xs'],
        ie: function(){
            var agent = navigator.userAgent.toLocaleLowerCase();
            return (!!window.ActiveXObject || "ActiveXObject" in window) ? ((agent.match(/msie\s(\d+)/) || [])[1] || '11') : false;
        },
        ready: function(callback){
            var cssName = 'luckyModal', ver = '',
                path = (isLucky ? 'modal/' : 'theme/') + "modal.css?v=" + modal.v + ver;
            isLucky ? lucky.addcss(path, callback, cssName) : ready.link(path, callback, cssName);
            return this;
        },
        open: function (options) {
            var modalConst = new ModalConst(options);
            return modalConst.index;
        },
        alert:function (content, options, yes) {
            var type = typeof options === 'function';
            if(type) yes = options;
            return modal.open($.extend({
                content: content,
                size:"xs",
                btn:[["确定","btn-danger"]],
                yes: yes
            }, type ? {} : options));
        },
        confirm: function (content, options, yes, cancel) {
            var type = typeof options === 'function';
            if(type){
                cancel = yes;
                yes = options;
            }
            return modal.open($.extend({
                title:"提醒",
                content: content,
                anim:3,
                size:"xs",
                btn:[["确定","btn-danger"],"取消"],
                yes: yes,
                btn2: cancel
            }, type ? {} : options));
        },
        msg: function (content, options, close) {
            var type = typeof options === 'function';
            if(type){
                close = options;
                options = {};
            }
            return modal.open($.extend({
                size:['auto','auto'],
                header: false,
                shade: false,
                closeBtn: false,
                content: content,
                time: 3000,
                skin: "lucky-modal-msg",
                close: close
            }, options));
        },
        load: function (content, options) {
            content = content ? content : "<i class='lucky-icon-load1 lucky-icon-spin'></i> 加载中";
            return modal.open($.extend({
                type:"loading",
                size:['auto','auto'],
                header: false,
                shade: "0.1",
                shadeClose:false,
                closeBtn: false,
                content: content
            }, options));
        },
        iframe: function (url, options, yes, cancel) {
            var type = typeof options === 'function';
            if(type){
                cancel = yes;
                yes = options;
            }
            return modal.open($.extend({
                title:"提醒",
                type:"iframe",
                content: url,
                size:"lg",
                btn:[["确定","btn-danger"],"取消"],
                yes: yes,
                btn2: cancel
            }, type ? {} : options));
        }
    };

    var doms = ['lucky-modal', 'lucky-modal-dialog', 'lucky-modal-content', 'lucky-modal-header', 'lucky-modal-title', 'lucky-modal-body', 'lucky-modal-footer'];
    doms.anim = ['fadeInDown', 'fadeIn', 'slideInDown', 'shake'];

    var ModalConst = function (settings) {
        var that = this;
        that.index = ++ modal.index;
        that.config = $.extend({}, that.config, ready.config, settings);
        doms.html = $('html');
        document.body ? that.create() : setTimeout(function(){
            that.create();
        },30);
    };

    ModalConst.prototype.config = {
        type: 'dialog',
        //Enum['','xl','lg','sm','xs']/String  size:'500px'自定义宽度 size:['500px','500px']  宽度,高度
        size: '',
        offset: 'auto',
        //String/Array/Boolean shade:[0.8, '#393D49'] shade: 0  shade:false
        shade: 0.3,
        shadeClose: true,
        header: true,
        //String/Array/Boolean title :'我是标题' title: ['文本', 'font-size:18px;'] title: false
        title: '\u4fe1\u606f',
        //Boolean/Function
        closeBtn: true,
        time: 0,
        autoHeight: 100,
        anim: 0,
        maxmin: false,
        zIndex: 20000,
        scrollbar: false
    };

    ModalConst.prototype.container = function(conType, callback){
        var that = this, times = that.index, config = that.config;
        var zIndex = config.zIndex + times, titype = typeof config.title === 'object';
        var closeBtn = (config.closeBtn || typeof config.closeBtn === 'function');
        var ismax = config.maxmin;
        var titleHTML = (config.title ? '<h4 class="lucky-modal-title" style="'+ (titype ? config.title[1] : '') +'">' + (titype ? config.title[0] : config.title) + '</h4>' : '<h4 class="lucky-modal-title"></h4>');

        config.zIndex = zIndex;

        callback([
            config.shade ? ('<div class="lucky-modal-backdrop" id="lucky-modal-backdrop'+ times +'" times="'+ times +'" style="'+ ('z-index:'+ (zIndex-1) +'; ') +'"></div>') : '',
            '<div class="lucky-modal '+ (config.skin ? config.skin:'') +' '+ (function(){
                /*设置dialog大小*/
                if($.isArray(config.size) && $.inArray(config.size[0],modal.sizeEnums) >-1){
                    return config.size[0] === '' ? "" : "lucky-modal-" + config.size[0];
                }
                return $.inArray(config.size,modal.sizeEnums) > -1 ? (config.size === '' ? '':"lucky-modal-" + config.size) : '';
            }()) +'" id="'+ doms[0] + times +'" times="'+ times +'" type="'+ config.type +'" style="z-index: '+ zIndex +';">'
                + '<div class="lucky-modal-dialog">'
                    + '<div class="lucky-modal-content" id="'+ (config.id||'') +'">'
                        + (function(){
                            return config.header ? (function(){
                                var headerHtml = '<div class="lucky-modal-header">'
                                + (titleHTML)
                                    + '<div class="lucky-action-group">'
                                        + (function(){
                                            /*设置dialog按钮*/
                                            var btns =  ismax ? "<a class=\"lucky-action lucky-minus\"><i class=\"lucky-icon-minus\"></i></a><a class=\"lucky-action lucky-max\"><i class=\"lucky-icon-max\"></i></a>" : "";
                                            closeBtn && (btns += "<a class=\"lucky-action lucky-close\"><i class=\"lucky-icon-close\"></i></a>");
                                            return btns;
                                        }())
                                    + '</div>'
                                + '</div>';
                                return headerHtml;
                            }()):'';
                        }())

                        + '<div class="lucky-modal-body">'
                            + (conType ? '' : (config.content || ''))
                        + '</div>'

                        + (function () {
                            return config.btn ? function () {
                                var buttons = '<div class="lucky-modal-footer">'
                                    + (function(){
                                        var button = '';
                                        typeof config.btn === 'string' && (config.btn = [config.btn]);
                                        for(var i = 0, len = config.btn.length; i < len; i++){
                                            var item = $.isArray(config.btn[i]) ? config.btn[i] : [config.btn[i], ''];
                                            item[1] = item[1] == undefined ? "": item[1];
                                            button += '<button type="button" class="btn btn-sm '+ item[1] +'" data-index="'+ i +'">'+ item[0] +'</button>';
                                        }
                                        return button;
                                    }())
                                    + '</div>';
                                return buttons;
                            }() : '';
                        }())
                    + '</div>'
                + '</div>'
            + '</div>'
        ], titleHTML, $('<div class="lucky-modal-move"></div>'));

        return that;
    };

    ModalConst.prototype.create = function () {
        var that = this,
        config = that.config,
        times = this.index, nodeIndex,
        content = config.content,
        conType = typeof content === 'object',
        body = $('body');

        if(config.id && $('#' + config.id)[0])
            return;

        if(typeof config.size === 'string'){
            config.size = (function () {
                if($.inArray(config.size, modal.sizeEnums) > -1){
                    return config.size;
                }
                return modal.sizeEnums[0];
            }());
        }
        switch (config.type) {
            case "dialog":
                modal.closeAll('dialog');
                break;
            case "loading":
                delete config.header;
                delete config.closeBtn;
                modal.closeAll('loading');
                break;
            case "iframe":
                config.content = conType ? config.content : [config.content || 'http://baidu.com', 'auto'];
                config.content = '<iframe scrolling="'+ (config.content[1] || 'auto') +'" allowtransparency="true" id="lucky-modal-iframe'+ times +'" times="'+ times +'" name="lucky-modal-iframe'+ times +'" onload="this.className=\'\';" frameborder="0" src="' + config.content[0] + '"></iframe>';
                break;
        }
        
        that.container(conType, function (html, titleHTML, moveElem) {
            body.append(html[0]);
            conType ? (function () {
                if(!content.parents('.'+doms[0])[0]){
                    body.append(html[1]);
                    $('#'+ doms[0] + times).find('.' + doms[5]).append(content);
                }else{
                    body.append(html[1]);
                }
            }()) : body.append(html[1]);

            $('.lucky-modal-move')[0] ||  body.append(ready.moveElem = moveElem);
            that.currentModal = $('#'+ doms[0] + times);
            config.scrollbar || doms.html.css('overflow', 'hidden');
        }).auto(times);

        config.type == ready.type[2] && $('#'+ doms[0] + times).addClass("lucky-modal-iframe");

        //遮罩
        $("#lucky-modal-backdrop" + that.index).css({
            'background-color': config.shade[1] || '#464855',
            'opacity': config.shade[0] || config.shade
        });

        doms.html.attr("modal-zindex",config.zIndex);

        that.offset().events(times);

        $(window).on('resize', function(){
            that.offset();
        });

        config.time <= 0 || setTimeout(function(){
            modal.close(that.index);
        }, config.time);

        if(doms.anim[config.anim]){
            var animClass = "animated " + doms.anim[config.anim];
            that.currentModal.addClass(animClass).one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
                $(this).removeClass(animClass);
            });
        }
    };

    ModalConst.prototype.auto = function(index){
        var that = this, config = that.config,
            currentModal = $('#'+ doms[0] + index),
            currentBody = currentModal.find("." + doms[5]),
            currentHeader = currentModal.find("." + doms[3]),
            currentFooter = currentModal.find("." + doms[6]),
            setHeight = function (elem, hg) {
                elem = currentModal.find(elem);
                elem.height(hg);
            };
        if($.inArray(config.size, modal.sizeEnums) == -1){
            var size = $.isArray(config.size) ? config.size : [config.size, 'auto'];
            var width = size[0], height = size[1];
            if(parseInt(height) > $(window).height()){
                height = $(window).height() + "px";
            }
            config.type === ready.type[2] ?  setHeight("iframe",height) : setHeight("." + doms[5], height);

            if($.inArray(width, modal.sizeEnums) == -1){
                currentModal.css("width",width);
            }
        }

        var dialogBodyHeight = currentBody.outerHeight(),
            windowHeight = $(window).height();

        if(dialogBodyHeight > windowHeight){
            windowHeight = (function () {
                var height = windowHeight - config.autoHeight;
                if(currentHeader[0]){
                    height = height - currentHeader.outerHeight();
                }
                if(currentFooter[0]){
                    height = height - currentFooter.outerHeight();
                }
                return height;
            }());
            setHeight("." + doms[5], windowHeight);
        }
    };

    ModalConst.prototype.offset = function(){
        var that = this, config = that.config, currentModal = that.currentModal;
        var size = [currentModal.width(), currentModal.height()];
        var type = (typeof config.offset === 'object' && $.isArray(config.offset) === true);
        var isObject = (typeof config.offset === 'object' && $.isArray(config.offset) === false);

        that.offsetTop = ($(window).height() - size[1])/2;
        that.offsetLeft = ($(window).width() - size[0])/2;

        if(type){
            that.offsetTop = config.offset[0];
            that.offsetLeft = config.offset[1] || that.offsetLeft;
        } else if(isObject){
            //对象元素
        } else if(config.offset !== 'auto'){
            if(config.offset === 't'){ //上
                that.offsetTop = 0;
            } else if(config.offset === 'r'){ //右
                that.offsetLeft = $(window).width() - size[0];
            } else if(config.offset === 'b'){ //下
                that.offsetTop = $(window).height() - size[1];
            } else if(config.offset === 'l'){ //左
                that.offsetLeft = 0;
            } else if(config.offset === 'lt'){ //左上角
                that.offsetTop = 0;
                that.offsetLeft = 0;
            } else if(config.offset === 'lb'){ //左下角
                that.offsetTop = $(window).height() - size[1];
                that.offsetLeft = 0;
            } else if(config.offset === 'rt'){ //右上角
                that.offsetTop = 0;
                that.offsetLeft = $(window).width() - size[0];
            } else if(config.offset === 'rb'){ //右下角
                that.offsetTop = $(window).height() - size[1];
                that.offsetLeft = $(window).width() - size[0];
            } else {
                that.offsetTop = config.offset;
            }
        }

        if(currentModal.attr('minLeft')){
            that.offsetTop = $(window).height() - (currentModal.find(doms[3]).outerHeight() || 0);
            that.offsetLeft = currentModal.css('left');
        }

        currentModal.css({top: that.offsetTop, left: that.offsetLeft});
        return that;
    };

    ModalConst.prototype.events = function(index){
        var that = this, config = that.config,
            currentDialog = $('#'+ doms[0] + index),
            shadeElement = $("#lucky-modal-backdrop" + index);
        var currentHeader = currentDialog.find("." + doms[3]), currentFooter = currentDialog.find("." + doms[6]);
        //关闭
        currentHeader.find(".lucky-close").on("click", function () {
            var cancel = config.close && config.close(index, currentDialog);
            cancel === false || modal.close(index);
        });
        //最大化
        currentHeader.find(".lucky-max").on("click", function () {
            if(doms.html.attr("modal-full") == index){
                modal.restore(index);
            }else{
                that.setTop(index);
                modal.fullscreen(index);
            }
        });
        //最小化
        currentHeader.find(".lucky-minus").on("click", function () {
            if(currentDialog.attr("modal-min") == index){
                modal.restore(index);
            }else{
                modal.min(index);
            }
        });
        if(config.shadeClose){
            shadeElement.on("click", function () {
                var cancel = config.close && config.close(index, currentDialog);
                cancel === false || modal.close(index);
            });
        }
        if(config.success){
            config.success(index, currentDialog);
        }

        currentFooter.children("button").on("click", function(){
            var index = $(this).index();
            if(index === 0){
                if(config.yes){
                    config.yes(that.index, currentDialog);
                } else if(config["btn1"]){
                    config["btn1"](that.index, currentDialog);
                } else {
                    modal.close(that.index);
                }
            } else {
                var eventBack = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, currentDialog);
                eventBack === false || modal.close(that.index);
            }
        });

        //窗口移动
        that.drag(index);
    };

    ModalConst.prototype.drag = function(index){
        var that = this, config = that.config,
            _DOC = $(document),
            currentModal = that.currentModal,
            dragElem = currentModal.find("." + doms[4]), dict = {};

        dragElem.on("mousedown", function (e) {
            e.preventDefault();
            that.setTop(index);
            dict.moveStart = true;
            dict.offset = [
                e.clientX - parseFloat(currentModal.css('left'))
                ,e.clientY - parseFloat(currentModal.css('top'))
            ];
            ready.moveElem.css('cursor', 'move').show();
        });

        _DOC.on("mousemove", function (e) {
            if(dict.moveStart){
                var X = e.clientX - dict.offset[0]
                    ,Y = e.clientY - dict.offset[1]
                    ,fixed = currentModal.css('position') === 'fixed';
            }
            e.preventDefault();

            dict.stX = fixed ? 0 : $(window).scrollLeft();
            dict.stY = fixed ? 0 : $(window).scrollTop();

            //控制元素不被拖出窗口外
            if(!config.moveOut){
                var setRig = $(window).width() - currentModal.outerWidth() + dict.stX
                    ,setBot = $(window).height() - currentModal.outerHeight() + dict.stY;
                X < dict.stX && (X = dict.stX);
                X > setRig && (X = setRig);
                Y < dict.stY && (Y = dict.stY);
                Y > setBot && (Y = setBot);
            }

            currentModal.css({
                left: X
                ,top: Y
            });
        }).on("mouseup", function(e){
            if(dict.moveStart){
                delete dict.moveStart;
                ready.moveElem.hide();
            }
            dragElem.css("cursor", "default");
        });

    };

    ModalConst.prototype.setTop = function(index){
        var that = this, config = that.config,
            currentDialog = $('#'+ doms[0] + index),
            currentShade = $("#lucky-modal-backdrop" + index);
        var zIndex = doms.html.attr("modal-zindex") ? parseInt(doms.html.attr("modal-zindex")) : config.zIndex;
        zIndex = config.zIndex = zIndex + 1;
        currentDialog.css('z-index', zIndex);
        if(currentShade[0]){
            currentShade.css('z-index',zIndex);
        }
        modal.index++;
        doms.html.attr("modal-zindex",config.zIndex);
    };

    ready.record = function(elem){
        var area = [
            elem.width(),
            elem.find("." + doms[5]).height(),
            elem.position().top,
            elem.position().left + parseFloat(elem.css('margin-left'))
        ];
        elem.find('.lucky-icon-max').addClass('lucky-icon-min');
        elem.find('.lucky-icon-minus').addClass('lucky-icon-minus-rest');
        elem.attr({area: area});
    };

    ready.rescollbar = function(index, clearHtmlStyle){
        var currentModal = $('#'+ doms[0] + index);
        if(clearHtmlStyle){
            if(doms.html[0].style.removeProperty){
                doms.html[0].style.removeProperty("overflow");
            }else{
                doms.html[0].style.removeAttribute("overflow");
            }
        }
        if(doms.html.attr("modal-full") == index){
            doms.html.removeAttr("modal-full");
        }
        if(currentModal.attr("modal-min") == index){
            currentModal.removeAttr("modal-min");
        }
    };

    window.modal = modal;

    modal.close = function(index){
        var currentModal = $('#'+ doms[0] + index);
        if(!currentModal[0]) return;
        $('#lucky-modal-backdrop' + index).remove();
        ready.rescollbar(index,true);
        currentModal.remove();
    };

    modal.closeAll = function(type){
        if($("." + doms[0]).length == 0){
            return;
        }
        $.each($("." + doms[0]), function () {
            var othis = $(this);
            var is = type ? (othis.attr("type") === type) : 1;
            is && modal.close(othis.attr("times"));
            is = null;
        });
    };

    modal.fullscreen = function(index){
        var currentModal = $('#'+ doms[0] + index),
            currentBody = currentModal.find("." + doms[5]),
            currentHeader = currentModal.find("." + doms[3]), currentFooter = currentModal.find("." + doms[6]);
        ready.record(currentModal);
        if(!doms.html.attr('modal-full')){
            doms.html.css('overflow','hidden').attr('modal-full', index);
        }
        var isfix = currentModal.css('position') === 'fixed';
        currentModal.css({
            top: isfix ? 0 : $(window).scrollTop(),
            left: isfix ? 0 : $(window).scrollLeft(),
            width: $(window).width()
        });

        var otherAreaHeight = (function () {
            var height = 0;
            if(currentHeader[0]){
                height += currentHeader.outerHeight();
            }
            if(currentBody[0]){
                height += (currentBody.outerHeight() - currentBody.height());
            }
            if(currentFooter[0]){
                height += currentFooter.outerHeight();
            }
            return height;
        }());
        currentBody.height($(window).height() - otherAreaHeight);
        currentModal.addClass("lucky-modal-max");
    };

    modal.min = function(index){
        var currentModal = $('#'+ doms[0] + index);
        if(!currentModal.attr("modal-min")){
            currentModal.attr('modal-min', index);
        }
        ready.record(currentModal);
        currentModal.css({
            top: 'inherit',
            left: 0,
            bottom: 0
        });
        currentModal.addClass("lucky-modal-minus");
    };

    modal.restore = function(index){
        var currentModal = $('#'+ doms[0] + index), currentBody = currentModal.find("." + doms[5]),
            area = currentModal.attr('area').split(',');
        currentModal.css({
            top: area[2] +"px",
            left: area[3] +"px",
            bottom:'inherit',
            width: area[0] +"px"
        });
        currentModal.find('.lucky-icon-max').removeClass('lucky-icon-min');
        currentModal.find('.lucky-icon-minus').removeClass('lucky-icon-minus-rest');
        currentModal.removeClass("lucky-modal-max");
        currentModal.removeClass("lucky-modal-minus");

        currentBody.height(area[1]);
        ready.rescollbar(index);
    };

    //获取子iframe Dom
    modal.getFrameDom = function(selector, index){
        index = index || $('.lucky-modal-iframe').attr('times');
        return $('#'+ doms[0] + index).find('iframe').contents().find(selector);
    };

    //获取子iframe form
    modal.getFrameForm = function(index, selector){
        selector = selector || ".form";
        return modal.getFrameDom(selector, index);
    };

    //获取当前iframe层的索引，子iframe时使用
    modal.getFrameIndex = function(name){
        return $('#'+ name).parents('.lucky-modal-iframe').attr('times');
    };

    window.lucky && lucky.define ? (
        modal.ready(),
        lucky.define('jquery', function(exports){
            modal.path = lucky.cache.dir;
            $ = window.jQuery;
            window.modal = modal;
            exports('modal', modal);
        })
    ):(
        (typeof define === 'function' && define.amd) ? define(['jquery'], function(){
            $ = window.jQuery;
            return modal;
        }) : function(){
            $ = window.jQuery;
            modal.ready();
        }()
    );
}(window);